package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

//菜品管理
@RestController
@RequestMapping("/dish")
public class DishController {
    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisTemplate redisTemplate;
    //新增菜品
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto){
        dishService.saveWithFlavor(dishDto);

        //清理某个分类下的菜品缓存数据
        String key = "dish_"+dishDto.getCategoryId()+"_1";
        redisTemplate.delete(key);

        return R.success("新增菜品成功");
    }

    //修改菜品
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){
        dishService.updateWithFlavor(dishDto);
        //清理所有菜品的缓存数据(清理所有dish开头的key)
        //Set keys = redisTemplate.keys("dish_*");
        //redisTemplate.delete(keys);

        //清理某个分类下的菜品缓存数据
        String key = "dish_"+dishDto.getCategoryId()+"_1";//直接写“_1”就可以，因为传过来的都是1
        redisTemplate.delete(key);

        return R.success("修改菜品成功");
    }





    //菜品信息分页查询
    @GetMapping("/page")
    public R<Page> page(int page,int pageSize,String name){
        //构造分页构造器对象
        Page<Dish> pageInfo = new Page<>(page,pageSize);
        Page<DishDto> dishDtoPage = new Page<>();


        LambdaQueryWrapper<Dish> queryWrapper =new LambdaQueryWrapper<>();
        queryWrapper.like(name !=null, Dish::getName,name);
        queryWrapper.orderByDesc(Dish::getUpdateTime);

        //分页查询
        dishService.page(pageInfo,queryWrapper);

        //拷贝对象（第三个参数是不拷贝的数据，records也就是我们列表展示的那些数据，因为这个数据有一个不能完全展示出来(可以去查看page的底层代码)）
        BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");

        List<Dish> records = pageInfo.getRecords(); //获取pageInfo的records（也就是dish表的数据）
        List<DishDto> list = records.stream().map((item)->{

            DishDto dishDto = new DishDto();//因为我们这里的是新new出来的，所以其他数据都是空的
            BeanUtils.copyProperties(item,dishDto);//这里先把Dish的数据拷贝进来，下面把category的分类数据拷贝进来

            Long categoryId = item.getCategoryId();//获取分类Id
            Category category = categoryService.getById(categoryId);//根据分类id查询category表的数据(因为这是我们导入的，会有些id没对应的名字)
            if(category !=null){
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            return dishDto;
        }).collect(Collectors.toList());


        dishDtoPage.setRecords(list); //接收上面的list对象
        return R.success(dishDtoPage);

    }

    //根据id查询菜品信息（用于修改菜品信息的回显）
    @GetMapping("/{id}")
    public R<DishDto> get(@PathVariable Long id){

        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);

    }


    //停售
    @PostMapping("/status/{status}")
    public R<String> status(@PathVariable Integer status, String id){
        String[] ids =  id.split(".");
        int arrayLength = ids.length;
        Integer[] idArray = new Integer[arrayLength];

        for (int i = 0 ;i<ids.length;i++){
            idArray[i] = Integer.parseInt(ids[i]);
        }

        ArrayList<Integer> integers = new ArrayList<>(arrayLength);
        Collections.addAll(integers,idArray);
        LambdaUpdateWrapper<Dish> updateWrapper = new LambdaUpdateWrapper();
        updateWrapper.set(Dish::getStatus,status);
        //如何将列表作为更新呢，或者如果把int字段一个一个拿出来呢

//            dish.setStatus(status);
//            dishService.updateById(dish);
//            return R.success(dish.getStatus() == 1?"已成功修改为'启用'":"已成功修改为'停售'");
return null;
    }


    /**
     * 根据条件查询对应的菜品数据
     * @param dish
     * @return
     */
  /*  @GetMapping("/list")
    public R<List<Dish>> list(Dish dish){
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dish.getCategoryId() !=null,Dish::getCategoryId,dish.getCategoryId())
                .eq(Dish::getStatus,1)
                .orderByAsc(Dish::getSort).orderByAsc(Dish::getUpdateTime);
        List<Dish> list = dishService.list(queryWrapper);

      return R.success(list);
    }*/


    @GetMapping("/list")  //原来的查询Dish的数据还是一样可以用，只是加入一些新的口味属性，用于添加购物车
    public R<List<DishDto>> list(Dish dish){
        List<DishDto> dishDtoList = null;

        //0、动态的构造key（它传过来的数据都是这种格式：http://localhost:8080/dish/list?categoryId=1397844303408574465&status=1）
        String key  = "dish_" + dish.getCategoryId()+"_"+dish.getStatus();

        //1、从redis中获取缓存数据（这里查询到的话，就不需要和以前一样重复查，浪费内存）
        dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);

        if(dishDtoList !=null){
            //2、如果存在，直接返回，无需查询数据库（不存在写在最下面）
            return R.success(dishDtoList);
        }


        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dish.getCategoryId() !=null,Dish::getCategoryId,dish.getCategoryId())
                .eq(Dish::getStatus,1)
                .orderByAsc(Dish::getSort).orderByAsc(Dish::getUpdateTime);
        List<Dish> list = dishService.list(queryWrapper);


         dishDtoList = list.stream().map((item)->{

              DishDto dishDto = new DishDto();//因为我们这里的是新new出来的，所以其他数据都是空的
              BeanUtils.copyProperties(item,dishDto);//这里先把Dish的数据拷贝进来，下面把category的分类数据拷贝进来

              Long categoryId = item.getCategoryId();//获取分类Id
              Category category = categoryService.getById(categoryId);//根据分类id查询category表的数据(因为这是我导入的其他，会有些id没对应的名字)
              if(category !=null){
                  String categoryName = category.getName();
                  dishDto.setCategoryName(categoryName);
              }

              //当前菜品的id
              Long dishId = item.getId();
              LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper= new LambdaQueryWrapper<>();
              lambdaQueryWrapper.eq(DishFlavor::getDishId,dishId);

              List<DishFlavor> dishFlavorList = dishFlavorService.list(lambdaQueryWrapper);
                dishDto.setFlavors(dishFlavorList);

              return dishDto;
          }).collect(Collectors.toList());


        //如果不存在，查询数据库，将查到的数据缓存到Redis
        redisTemplate.opsForValue().set(key,dishDtoList,60, TimeUnit.MINUTES);



      return R.success(dishDtoList);
    }

}

